﻿using System;
using System.Configuration;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Globalization;
using System.Threading;
using AspNetMvc.MvcFrameworkUtils;
using Infrastructure.IP;
using PublicDomain.ZoneInfo;
using UsersProvider.Repositories.RelationalRepositories;
using WebGuiMvc.Models;
using WebGuiMvc.Helpers;
using System.IO;

namespace AspNetMvc
{
   public class MvcApplication : HttpApplication
   {
      public static void RegisterRoutes(RouteCollection routes)
      {
         routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
         // favicon workaround: http://stackoverflow.com/questions/1978921/asp-net-mvc-why-is-a-controller-being-created-for-favicon-ico
         routes.IgnoreRoute("favicon.ico");
         routes.IgnoreRoute("Content/{*pathInfo}");

         routes.MapRoute("Root",
                         "",
                         new { controller = "search", action = "index" });

         routes.MapRoute("Error", "error", new { controller = "general", action = "error" });

         routes.MapRoute("IE6NoMore",
                         "ie6nomore",
                         new { controller = "general", action = "ie6nomore" });

         routes.MapRoute("SearchResults", // Route name
                         "search", // URL with parameters
                         new { controller = "search", action = "search" } // Parameter defaults
            );

         routes.MapRoute("NewEvent", // Route name
                         "new", // URL with parameters
                         new { controller = "event", action = "new" } // Parameter defaults
            );

         routes.MapRoute("MyEvents",
                         "myevents",
                         new { controller = "event", action = "myevents" });

         routes.MapRoute("EventOperation", // Route name
                         "event/{id}/{action}", // URL with parameters
                         new { controller = "event" }, // Parameter defaults
                         new { id = @"\d+" }
            );

         routes.MapRoute("EventFullDisplay", // Route name
                         "event/{id}", // URL with parameters
                         new { controller = "event", action = "fulldisplay" }, // Parameter defaults
                         new { id = @"\d+" }
            );

         routes.MapRoute("Default", // Route name
                         "{controller}/{action}/{id}", // URL with parameters
                         new { id = UrlParameter.Optional } // Parameter defaults
            );
      }

      protected void Application_Start()
      {
         ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory());

         RegisterRoutes(RouteTable.Routes);

         Database.LoadFiles(ConfigurationManager.AppSettings["TzDatabasePath"]);
      }

      protected void Application_BeginRequest()
      {
         try
         {
            DomainHelper.RedirectToNonWww();

            if (Request.Browser.Browser == "IE" &&
               Convert.ToSingle(Request.Browser.Version) < 7.0 && !Request.RawUrl.ToUpper().Contains("IE6NOMORE"))
            {
               Response.Redirect("/ie6nomore");
            }
         }
         catch (Exception ex)
         {
            //ToDo: log it
         }
      }

      protected void Application_AcquireRequestState(object sender, EventArgs e)
      {
         //Очень важно проверять готовность объекта сессии
         if (HttpContext.Current.Session != null)
         {
            if (!string.IsNullOrEmpty(User.Identity.Name))
            {
               Session["Profile"] = Session["Profile"] ?? new ProfileModel((new UsersRepository()).GetUserByLogin(User.Identity.Name));
            }

            var profile = Session["Profile"] as ProfileModel;
            CultureInfo ci = this.Session["Culture"] as CultureInfo;

            if (profile != null) ci = string.IsNullOrEmpty(profile.Language) ? new CultureInfo("en") : new CultureInfo(profile.Language);
            //Вначале проверяем, что в сессии нет значения
            //и устанавливаем значение по умолчанию
            //это происходит при первом запросе пользователя
            if (ci == null)
            {
               //Устанавливает значение по умолчанию - базовый английский
               //Пытаемся получить значения с HTTP заголовка
               //if (HttpContext.Current.Request.UserLanguages != null && HttpContext.Current.Request.UserLanguages.Length != 0)
               //{
               //   //Получаем список
               //   //надо бы переделать
               //   string langName = HttpContext.Current.Request.UserLanguages[0].Substring(0, 2);
               //   ci = new CultureInfo(langName);
               //}

               IpToCultureInfoConverter ipToCultureInfoConverter = new IpToCultureInfoConverter(new IpToNumberConverter(), new CountryCodesRepository());

               ci = ipToCultureInfoConverter.GetCultureInfo(Request.UserHostAddress);

               this.Session["Culture"] = ci;
            }

            //Устанавливаем культуру для каждого запроса
            Thread.CurrentThread.CurrentUICulture = ci;
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(ci.Name);
            this.Session["Language"] = ci.TwoLetterISOLanguageName;
         }
      }

      protected void Application_Error(object sender, EventArgs e)
      {
         string userName = "";
         if (HttpContext.Current.User != null)
            userName = HttpContext.Current.User.Identity.Name;

         // Code that runs when an unhandled error occurs
         Exception exception = Server.GetLastError().GetBaseException();
         string errorText = "URL: " + Request.Url.ToString() + Environment.NewLine +
            "UserName: " + userName + Environment.NewLine +
                      "IP: " + Request.UserHostAddress + Environment.NewLine +
                      "Error Message: " + exception.Message.ToString();

         // Log the error
         try
         {
             if (!Directory.Exists("~Logs"))
                 Directory.CreateDirectory("~Logs");
            string path = "~/Logs/" + DateTime.Today.ToString("dd-mm-yy") + ".txt";
            if (!File.Exists(System.Web.HttpContext.Current.Server.MapPath(path)))
            {
               File.Create(System.Web.HttpContext.Current.Server.MapPath(path)).Close();
            }
            using (StreamWriter w = File.AppendText(System.Web.HttpContext.Current.Server.MapPath(path)))
            {
               w.WriteLine("Log Entry: ");
               w.WriteLine("DateTime: ", DateTime.Now.ToString());
               w.WriteLine(errorText);
               w.WriteLine();
               w.WriteLine();
               w.Flush();
               w.Close();
            }
         }
         catch (Exception ex)
         {
            // We hope here won't be an error
         }

         Server.ClearError();
         Response.Redirect("/error");
      }
   }
}